<?php
/**
 * SocialEngine
 *
 * @category   Application_Extensions
 * @package    Like
 * @copyright  Copyright Hire-Experts LLC
 * @license    http://www.hire-experts.com
 * @version    $Id: Core.php 2010-09-07 16:05 idris $
 * @author     Idris
 */

/**
 * @category   Application_Extensions
 * @package    Like
 * @copyright  Copyright Hire-Experts LLC
 * @license    http://www.hire-experts.com
 */

class Like_Api_Core extends Core_Api_Abstract {
	
	protected $_itemTypes = array ('album', 'blog', 'album_photo', 'video', 'classified', 'classified_photo', 'music_playlist', 'group_photo', 'event_photo', 'quiz', 'poll' );
	
	protected $_itemTypesLabel = array ('page' => 'Pages', 'event' => 'Events', 'event_photo' => 'Events Photos', 'classified' => 'Classifieds', 'group' => 'Groups', 'group_photo' => 'Groups Photos', 'user' => 'Members', 'music_playlist' => 'Music Playlists', 'blog' => 'Blogs', 'video' => 'Videos', 'album' => 'Albums', 'album_photo' => 'Photos', 'pageblog' => 'Page Blogs', 'playlist' => 'Page Music Playlists', 'pagealbum' => 'Page Albums', 'pagealbumphoto' => 'Page Album Photos', 'pagevideo' => 'Page Videos', 'quiz' => 'Quizzes', 'poll' => 'Polls', 'pagereview' => 'Page Reviews' );
	
	protected $_itemTypesIcons = array ('page' => '/application/modules/Like/externals/images/icons/page.png', 'event' => '/application/modules/Like/externals/images/icons/event.png', 'event_photo' => '/application/modules/Like/externals/images/icons/photo.png', 'classified' => '/application/modules/Like/externals/images/icons/classified.png', 'group' => '/application/modules/Like/externals/images/icons/group.png', 'group_photo' => '/application/modules/Like/externals/images/icons/photo.png', 'user' => '/application/modules/Like/externals/images/icons/user.png', 'music_playlist' => '/application/modules/Like/externals/images/icons/music_playlist.png', 'blog' => '/application/modules/Like/externals/images/icons/blog.png', 'video' => '/application/modules/Like/externals/images/icons/video.png', 'album' => '/application/modules/Like/externals/images/icons/album.png', 'album_photo' => '/application/modules/Like/externals/images/icons/photo.png', 'pageblog' => '/application/modules/Like/externals/images/icons/blog.png', 'playlist' => '/application/modules/Like/externals/images/icons/music_playlist.png', 'pagealbum' => '/application/modules/Like/externals/images/icons/album.png', 'pagealbumphoto' => '/application/modules/Like/externals/images/icons/photo.png', 'pagevideo' => '/application/modules/Like/externals/images/icons/video.png', 'quiz' => '/application/modules/Like/externals/images/icons/quiz.png', 'poll' => '/application/modules/Like/externals/images/icons/poll.png', 'pagereview' => '/application/modules/Like/externals/images/icons/review.png' );
	
	protected $_interestTypes = array ('page' => 'Pages', 'event' => 'Events', 'classified' => 'Classifieds', 'group' => 'Groups', 'music_playlist' => 'Music', 'blog' => 'Blogs', 'video' => 'Videos', 'album' => 'Albums', 'quiz' => 'Quizzes', 'poll' => 'Polls' );
	
	protected $_interestIcons = array ('page' => '/application/modules/Like/externals/images/icons/page.png', 'event' => '/application/modules/Like/externals/images/icons/event.png', 'classified' => '/application/modules/Like/externals/images/icons/classified.png', 'group' => '/application/modules/Like/externals/images/icons/group.png', 'blog' => '/application/modules/Like/externals/images/icons/blog.png', 'video' => '/application/modules/Like/externals/images/icons/video.png', 'album' => '/application/modules/Like/externals/images/icons/album.png', 'quiz' => '/application/modules/Like/externals/images/icons/quiz.png', 'poll' => '/application/modules/Like/externals/images/icons/poll.png' );
	
	protected $_nophotos = array ('blog' => '/application/modules/Like/externals/images/nophoto/blog.png', 'page' => '/application/modules/Like/externals/images/nophoto/page.png', 'event' => '/application/modules/Like/externals/images/nophoto/event.png', 'group' => '/application/modules/Like/externals/images/nophoto/group.png', 'classified' => '/application/modules/Like/externals/images/nophoto/classified.png', 'album' => '/application/modules/Like/externals/images/nophoto/album.png', 'video' => '/application/modules/Like/externals/images/nophoto/video.png', 'music_playlist' => '/application/modules/Like/externals/images/nophoto/music.png', 'quiz' => '/application/modules/Like/externals/images/nophoto/quiz.png', 'poll' => '/application/modules/Like/externals/images/nophoto/poll.png', 'pagereview' => '/application/modules/Like/externals/images/nophoto/pagereview.png' );
	
	protected $_pluginLoader;
	
	public function getSupportedModules() {
		return $this->_itemTypes;
	}
	
	public function getNoPhotos() {
		return $this->_nophotos;
	}
	
	public function getSupportedModulesLabels() {
		return $this->_itemTypesLabel;
	}
	
	public function getSupportedModulesIcons() {
		return $this->_itemTypesIcons;
	}
	
	public function getInterestTypes() {
		return $this->_interestTypes;
	}
	
	public function getInterestIcons() {
		return $this->_interestIcons;
	}
	
	public function getPluginLoader() {
		if (null === $this->_pluginLoader) {
			$path = Engine_Api::_ ()->getModuleBootstrap ( 'like' )->getModulePath ();
			$this->_pluginLoader = new Zend_Loader_PluginLoader ( array ('Like_Model_Helper_' => $path . '/Model/Helper/' ) );
		}
		
		return $this->_pluginLoader;
	}
	
	public function removePhotos() {
		$settings = Engine_Api::_ ()->getApi ( 'settings', 'core' );
		$file_id = $settings->getSetting ( 'like.logo' );
		
		if (isset ( $file_id ) && $file_id != 0) {
			$storage = Engine_Api::_ ()->storage ();
			$file = $storage->get ( $file_id );
			if ($file !== null)
				$file->remove ();
		}
	}
	
	public function getLogo() {
		$this->view->base_url = $baseUrl = 'http://' . $_SERVER ['HTTP_HOST'];
		
		$settings = Engine_Api::_ ()->getApi ( 'settings', 'core' );
		$storage = Engine_Api::_ ()->storage ();
		
		$file_id = $settings->getSetting ( 'like.logo' );
		
		if ($file_id) {
			$file = $storage->get ( $file_id );
			if ($file) {
				return $baseUrl . $file->map ();
			} else {
				return '';
			}
		} else {
			return '';
		}
	}
	
	public function getActionContent($object) {
		$viewer = Engine_Api::_ ()->user ()->getViewer ();
		$api = Engine_Api::_ ()->like ();
		$db = $api->getTable ()->getAdapter ();
		
		$params = array ('resource_type' => $object->getType (), 'resource_id' => $object->getIdentity (), 'fetch' => 'user_id' );
		$select = $api->getLikesSelect ( $params );
		
		$user_ids = $db->fetchCol ( $select );
		$item_ids = array ();
		$counter = 0;
		foreach ( $user_ids as $id ) {
			$item_ids [] = $id;
			$counter ++;
			if ($counter == 5) {
				break;
			}
		}
		if (! empty ( $item_ids )) {
			$users = Engine_Api::_ ()->getItemMulti ( 'user', $item_ids );
		} else {
			$users = array ();
		}
		
		$likeCount = ( int ) $api->getLikeCount ( $object );
		
		$view = Zend_Registry::get ( 'Zend_View' );
		$html = $view->partial ( '_composeLikeAction.tpl', 'like', array ('subject' => $viewer, 'users' => $users, 'user_ids' => $user_ids, 'object' => $object, 'likeCount' => $likeCount ) );
		
		return $html;
	}
	
	public function getActionContentPrivate(Core_Model_Item_Abstract $object) {
		$viewer = Engine_Api::_ ()->user ()->getViewer ();
		
		$view = Zend_Registry::get ( 'Zend_View' );
		$html = $view->partial ( '_composeLikeActionPrivate.tpl', 'like', array ('subject' => $viewer, 'object' => $object ) );
		
		return $html;
	}
	
	public function addAction($object, $user = null) {
		if ($user === null) {
			$user = Engine_Api::_ ()->user ()->getViewer ();
		}
		
		if (is_numeric ( $user )) {
			$user = Engine_Api::_ ()->getItem ( 'user', $user );
		}
		
		if (! ($user instanceof User_Model_User) || ! $user->getIdentity ()) {
			return null;
		}
		
		if (is_string ( $object )) {
			$object = Engine_Api::_ ()->getItemByGuid ( $object );
		}
		
		if (! ($object instanceof Core_Model_Item_Abstract) || ! $object->getIdentity ()) {
			return null;
		}
		
		$db = $this->getTable ()->getAdapter ();
		$db->beginTransaction ();
		
		try {
			$oldAction = $this->getAction ( $object );
			
			$actionType = 'like_item';
			$activityApi = Engine_Api::_ ()->getDbtable ( 'actions', 'activity' );
			$action = $activityApi->addActivity ( $user, $object, $actionType, '', array ('content' => $this->getActionContent ( $object ) ) );
			$action->date = date ( 'Y-m-d H:i:s' );
			$action->save ();
			
			if ($oldAction) {
				$this->updateActionStaff ( $oldAction, $action );
				$oldAction->deleteItem ();
			}
			
			$db->commit ();
		} catch ( Exception $e ) {
			$db->rollBack ();
			throw $e;
		}
		
		return $action;
	}
	
	public function updateActionStaff(Core_Model_Item_Abstract $oldAction, Core_Model_Item_Abstract $newAction) {
		$db = $this->getTable ()->getAdapter ();
		$db->beginTransaction ();
		
		try {
			$commentsApi = Engine_Api::_ ()->getDbTable ( 'comments', 'activity' );
			$likesApi = Engine_Api::_ ()->getDbTable ( 'likes', 'activity' );
			
			if ($oldAction->getIdentity () && $newAction->getIdentity ()) {
				$newAction->comment_count = $oldAction->comment_count;
				$newAction->like_count = $oldAction->like_count;
				
				$commentsApi->update ( array ('resource_id' => $newAction->action_id ), array ('resource_id = ?' => $oldAction->action_id ) );
				$likesApi->update ( array ('resource_id' => $newAction->action_id ), array ('resource_id = ?' => $oldAction->action_id ) );
				
				$newAction->save ();
			}
			
			$db->commit ();
		} catch ( Exception $e ) {
			
			$db->rollBack ();
			throw $e;
		}
	}
	
	public function deleteAction($object) {
		if (is_string ( $object )) {
			$object = Engine_Api::_ ()->getItemByGuid ( $object );
		}
		
		if (! ($object instanceof Core_Model_Item_Abstract) || ! $object->getIdentity ()) {
			return null;
		}
		
		$this->addAction ( $object );
	}
	
	public function isAllowed(Core_Model_Item_Abstract $subject) {
		$api = Engine_Api::_ ()->getDbTable ( 'permissions', 'authorization' );
		$action = 'like_' . $subject->getType ();
		$owner = $subject->getOwner ();
		return $api->isAllowed ( $owner, $owner, $action );
	}
	
	public function getAction($object) {
		if (is_string ( $object )) {
			$object = Engine_Api::_ ()->getItemByGuid ( $object );
		}
		
		if (! ($object instanceof Core_Model_Item_Abstract) || ! $object->getIdentity ()) {
			return null;
		}
		
		$actionType = 'like_item';
		$activityApi = Engine_Api::_ ()->getDbtable ( 'actions', 'activity' );
		
		$select = $activityApi->select ()->where ( 'object_type = ?', $object->getType () )->where ( 'object_id = ?', $object->getIdentity () )->where ( 'type = ?', $actionType );
		
		$action = $activityApi->fetchRow ( $select );
		
		return $action;
	}
	
	public function setPhoto($photo) {
		if ($photo instanceof Zend_Form_Element_File) {
			$file = $photo->getFileName ();
		} else if (is_array ( $photo ) && ! empty ( $photo ['tmp_name'] )) {
			$file = $photo ['tmp_name'];
		} else if (is_string ( $photo ) && file_exists ( $photo )) {
			$file = $photo;
		} else {
			throw new Event_Model_Exception ( 'invalid argument passed to setPhoto' );
		}
		
		$name = basename ( $file );
		$path = APPLICATION_PATH . DIRECTORY_SEPARATOR . 'temporary';
		$params = array ('parent_id' => ( int ) rand ( 0, 10000 ), 'parent_type' => 'like' );
		
		// Remove photos
		$this->removePhotos ();
		
		// Save
		$storage = Engine_Api::_ ()->storage ();
		
		// Resize image (icon)
		$image = Engine_Image::factory ();
		$image->open ( $file );
		
		if ($image->height != 16 && $image->width != 16) {
			
			$size = min ( $image->height, $image->width );
			$x = ($image->width - $size) / 2;
			$y = ($image->height - $size) / 2;
			
			$image->resample ( $x, $y, $size, $size, 16, 16 )->write ( $path . '/i_' . $name )->destroy ();
			
			$filename = $path . '/i_' . $name;
		} else {
			$filename = $file;
		}
		
		// Store
		$iIcon = $storage->create ( $filename, $params );
		
		$settings = Engine_Api::_ ()->getApi ( 'settings', 'core' );
		$settings->setSetting ( 'like.logo', $iIcon->file_id );
		
		return $iIcon;
	}
	
	public function isLike($object, $user = null) {
		if ($user === null) {
			$user = Engine_Api::_ ()->user ()->getViewer ();
		}
		
		if (is_numeric ( $user )) {
			$user = Engine_Api::_ ()->getItem ( 'user', $user );
		}
		
		if (! ($user instanceof User_Model_User) || ! $user->getIdentity ()) {
			return null;
		}
		
		if (is_string ( $object )) {
			$object = Engine_Api::_ ()->getItemByGuid ( $object );
		}
		
		if (! ($object instanceof Core_Model_Item_Abstract) || ! $object->getIdentity ()) {
			return null;
		}
		
		$table = Engine_Api::_ ()->getDbTable ( 'likes', 'core' );
		return ( bool ) $table->isLike ( $object, $user );
	}
	
	public function like($object, $user = null) {
		if ($user === null) {
			$user = Engine_Api::_ ()->user ()->getViewer ();
		}
		
		if (is_numeric ( $user )) {
			$user = Engine_Api::_ ()->getItem ( 'user', $user );
		}
		
		if (! ($user instanceof User_Model_User) || ! $user->getIdentity ()) {
			return null;
		}
		
		if (is_string ( $object )) {
			$object = Engine_Api::_ ()->getItemByGuid ( $object );
		}
		
		if (! ($object instanceof Core_Model_Item_Abstract) || ! $object->getIdentity ()) {
			return null;
		}
		
		$table = Engine_Api::_ ()->getDbTable ( 'likes', 'core' );
		$table->addLike ( $object, $user );
		
		if (! $user->isSelf ( $object )) {
			$actionType = 'like_item_private';
			$activityApi = Engine_Api::_ ()->getDbtable ( 'actions', 'activity' );
			$privateAction = $activityApi->addActivity ( $user, $object, $actionType, '', array ('content' => $this->getActionContentPrivate ( $object ) ) );
		}
		
		$event = Engine_Hooks_Dispatcher::getInstance ()->callEvent ( 'like', array ('object' => $object, 'user' => $user ) );
		
		return true;
	}
	
	public function unlike($object, $user = null) {
		if ($user === null) {
			$user = Engine_Api::_ ()->user ()->getViewer ();
		}
		
		if (is_numeric ( $user )) {
			$user = Engine_Api::_ ()->getItem ( 'user', $user );
		}
		
		if (! ($user instanceof User_Model_User) || ! $user->getIdentity ()) {
			return null;
		}
		
		if (is_string ( $object )) {
			$object = Engine_Api::_ ()->getItemByGuid ( $object );
		}
		
		if (! ($object instanceof Core_Model_Item_Abstract) || ! $object->getIdentity ()) {
			return null;
		}
		
		$table = Engine_Api::_ ()->getDbTable ( 'likes', 'core' );
		$table->removeLike ( $object, $user );
		
		$event = Engine_Hooks_Dispatcher::getInstance ()->callEvent ( 'unlike', array ('object' => $object, 'user' => $user ) );
		
		if (! $user->isSelf ( $object )) {
			$actionType = 'like_item_private';
			$activityApi = Engine_Api::_ ()->getDbtable ( 'actions', 'activity' );
			
			$select = $activityApi->select ()->where ( 'object_type = ?', $object->getType () )->where ( 'object_id = ?', $object->getIdentity () )->where ( 'type = ?', $actionType );
			
			$action = $activityApi->fetchRow ( $select );
			if ($action) {
				$action->deleteItem ();
			}
		}
		
		return true;
	}
	
	public function getLikesSelect($params, $period = 'all') {
		$userTable = Engine_Api::_ ()->getItemTable ( 'user' );
		$UTname = $userTable->info ( 'name' );
		
		$likeTable = Engine_Api::_ ()->getDbTable ( 'likes', 'core' );
		$LTname = $likeTable->info ( 'name' );
		
		$membershipTable = Engine_Api::_ ()->getDbTable ( 'membership', 'user' );
		$MTname = $membershipTable->info ( 'name' );
		
		$select = $likeTable->select ()->setIntegrityCheck ( false );
		
		if (! empty ( $params ['fetch'] )) {
			if ($params ['fetch'] == 'user_id') {
				$select->from ( array ('like1' => $LTname ), array () )->joinLeft ( array ('user' => $UTname ), 'user.user_id = like1.poster_id', array ('user.user_id' ) );
			} elseif ($params ['fetch'] == 'resource') {
				$select->from ( array ('like1' => $LTname ), array ('like1.resource_type', 'like1.resource_id' ) )->joinLeft ( array ('user' => $UTname ), 'user.user_id = like1.poster_id', array () );
			} else {
				$select->from ( array ('like1' => $LTname ), array () )->joinLeft ( array ('user' => $UTname ), 'user.user_id = like1.poster_id' );
			}
			if ($period == 'month') {
				$select->where ( 'like1.creation_date > ?', new Zend_Db_Expr ( 'DATE_SUB(NOW(), INTERVAL 1 MONTH)' ) );
			} elseif ($period == 'week') {
				$select->where ( 'like1.creation_date > ?', new Zend_Db_Expr ( 'DATE_SUB(NOW(), INTERVAL 1 WEEK)' ) );
			}
		} else {
			$select->from ( array ('like1' => $LTname ), array () )->joinLeft ( array ('user' => $UTname ), 'user.user_id = like1.poster_id' );
			if ($period == 'month') {
				$select->where ( 'like1.creation_date > ?', new Zend_Db_Expr ( 'DATE_SUB(NOW(), INTERVAL 1 MONTH)' ) );
			} elseif ($period == 'week') {
				$select->where ( 'like1.creation_date > ?', new Zend_Db_Expr ( 'DATE_SUB(NOW(), INTERVAL 1 WEEK)' ) );
			}
		}
		
		if (! empty ( $params ['keyword'] )) {
			$select->where ( "user.username LIKE '%{$params['keyword']}%' OR user.displayname LIKE '%{$params['keyword']}%'" );
		}
		
		if (! empty ( $params ['mutual'] )) {
			$select->joinLeft ( array ('like2' => $LTname ), 'like1.resource_id = like2.resource_id AND like1.resource_type = like2.resource_type', array () )->where ( 'like2.poster_id = ?', $params ['mutual'] )->where ( 'like2.poster_type = ?', 'user' );
			if ($period == 'month') {
				$select->where ( 'like2.creation_date > ?', new Zend_Db_Expr ( 'DATE_SUB(NOW(), INTERVAL 1 MONTH)' ) );
			} elseif ($period == 'week') {
				$select->where ( 'like2.creation_date > ?', new Zend_Db_Expr ( 'DATE_SUB(NOW(), INTERVAL 1 WEEK)' ) );
			}
		}
		
		if (! empty ( $params ['resource_type'] )) {
			if (is_array ( $params ['resource_type'] )) {
				$where = 'like1.resource_type IN ("' . implode ( '","', $params ['resource_type'] ) . '")';
				$select->where ( $where );
			} else {
				$select->where ( 'like1.resource_type = ?', $params ['resource_type'] );
			}
			if ($period == 'month') {
				$select->where ( 'like1.creation_date > ?', new Zend_Db_Expr ( 'DATE_SUB(NOW(), INTERVAL 1 MONTH)' ) );
			} elseif ($period == 'week') {
				$select->where ( 'like1.creation_date > ?', new Zend_Db_Expr ( 'DATE_SUB(NOW(), INTERVAL 1 WEEK)' ) );
			}
		}
		
		if (! empty ( $params ['resource_id'] )) {
			$select->where ( 'like1.resource_id = ?', $params ['resource_id'] );
			if ($period == 'month') {
				$select->where ( 'like1.creation_date > ?', new Zend_Db_Expr ( 'DATE_SUB(NOW(), INTERVAL 1 MONTH)' ) );
			} elseif ($period == 'week') {
				$select->where ( 'like1.creation_date > ?', new Zend_Db_Expr ( 'DATE_SUB(NOW(), INTERVAL 1 WEEK)' ) );
			}
		}
		
		if (! empty ( $params ['poster_type'] )) {
			$select->where ( 'like1.poster_type = ?', $params ['poster_type'] );
			if ($period == 'month') {
				$select->where ( 'like1.creation_date > ?', new Zend_Db_Expr ( 'DATE_SUB(NOW(), INTERVAL 1 MONTH)' ) );
			} elseif ($period == 'week') {
				$select->where ( 'like1.creation_date > ?', new Zend_Db_Expr ( 'DATE_SUB(NOW(), INTERVAL 1 WEEK)' ) );
			}
		}
		
		if (! empty ( $params ['poster_id'] )) {
			$select->where ( 'like1.poster_id = ?', $params ['poster_id'] );
			if ($period == 'month') {
				$select->where ( 'like1.creation_date > ?', new Zend_Db_Expr ( 'DATE_SUB(NOW(), INTERVAL 1 MONTH)' ) );
			} elseif ($period == 'week') {
				$select->where ( 'like1.creation_date > ?', new Zend_Db_Expr ( 'DATE_SUB(NOW(), INTERVAL 1 WEEK)' ) );
			}
		}
		
		if (! empty ( $params ['friend_id'] )) {
			$select->joinInner ( array ('membership' => $MTname ), 'membership.user_id = user.user_id', array () )->where ( 'membership.resource_id = ?', $params ['friend_id'] )->where ( 'membership.resource_approved = 1' )->where ( 'membership.user_approved = 1' );
		}
		
		if (! empty ( $params ['limit'] )) {
			$select->limit ( $params ['limit'] );
		}
		
		return $select;
	}
	
	public function getTable() {
		return Engine_Api::_ ()->getDbTable ( 'likes', 'core' );
	}
	
	public function getMatches(User_Model_User $subject) {
		$uTable = Engine_Api::_ ()->getItemTable ( 'user' );
		$UTname = $uTable->info ( 'name' );
		
		$lTable = Engine_Api::_ ()->getDbTable ( 'likes', 'core' );
		$LTname = $lTable->info ( 'name' );
		
		$innerSelect = $lTable->select ()->setIntegrityCheck ( false )->from ( $LTname, array ('resource_type', 'resource_id' ) )->where ( 'poster_id = ?', $subject->getIdentity () );
		
		$select = $lTable->select ()->setIntegrityCheck ( false )->from ( array ('like1' => $LTname ), array ('count' => 'COUNT(*)', 'poster_id' ) )->joinInner ( array ('tmp' => $innerSelect ), 'tmp.resource_type = like1.resource_type' )->where ( 'tmp.resource_id = like1.resource_id' )->where ( 'like1.poster_id <> ?', $subject->getIdentity () )->group ( 'like1.poster_id' );
		
		$db = $uTable->getAdapter ();
		
		$all = $db->fetchAll ( $select );
		$counts = array ();
		$user_ids = array ();
		foreach ( $all as $data ) {
			$user_id = $data ['poster_id'];
			$counts [$user_id] = $data ['count'];
			$user_ids [] = $user_id;
		}
		
		if (! empty ( $user_ids )) {
			$select = $uTable->select ()->where ( 'user_id IN (' . implode ( ',', $user_ids ) . ')' );
			return array ('paginator' => Zend_Paginator::factory ( $select ), 'counts' => $counts );
		} else {
			return array ('paginator' => Zend_Paginator::factory ( array () ), 'counts' => $counts );
		}
	}
	
	public function getMatchedItems(User_Model_User $subject, $user_id) {
		$uTable = Engine_Api::_ ()->getItemTable ( 'user' );
		$UTname = $uTable->info ( 'name' );
		
		$lTable = Engine_Api::_ ()->getDbTable ( 'likes', 'core' );
		$LTname = $lTable->info ( 'name' );
		
		$innerSelect = $lTable->select ()->setIntegrityCheck ( false )->from ( $LTname, array ('resource_type', 'resource_id' ) )->where ( 'poster_id = ?', $subject->getIdentity () );
		
		$select = $lTable->select ()->setIntegrityCheck ( false )->from ( array ('like1' => $LTname ) )->joinInner ( array ('tmp' => $innerSelect ), 'tmp.resource_type = like1.resource_type' )->where ( 'tmp.resource_id = like1.resource_id' )->where ( 'like1.poster_id = ?', $user_id );
		
		$db = $uTable->getAdapter ();
		
		$all = $db->fetchAll ( $select );
		$items = array ();
		foreach ( $all as $data ) {
			$items [] = Engine_Api::_ ()->getItem ( $data ['resource_type'], $data ['resource_id'] );
		}
		
		return Zend_Paginator::factory ( $items );
	}
	
	public function getLikes($object, $period = 'all') {
		if (is_string ( $object )) {
			$object = Engine_Api::_ ()->getItemByGuid ( $object );
		} elseif (is_array ( $object )) {
			$viewer = Engine_Api::_ ()->user ()->getViewer ();
			
			$params = array ('resource_type' => $object ['object'], 'resource_id' => $object ['object_id'], 'period_type' => $object ['period_type'] );
			$period = $params ['period_type'];
			if (isset ( $object ['list_type'] ) && $object ['list_type'] === 'mutual') {
				$params ['friend_id'] = $viewer->getIdentity ();
			}
			
			if (! empty ( $object ['keyword'] )) {
				$params ['keyword'] = $object ['keyword'];
			}
			$params ['fetch'] = 'user_id';
			
			$select = $this->getLikesSelect ( $params, $period );
			$db = $this->getTable ()->getAdapter ();
			$user_ids = $db->fetchCol ( $select );
			
			return Zend_Paginator::factory ( Engine_Api::_ ()->getItemMulti ( 'user', $user_ids ) );
		}
		
		if (! ($object instanceof Core_Model_Item_Abstract) || ! $object->getIdentity ()) {
			return null;
		}
		$select = $this->getAllLikesUsers ( $object, $period );
		return Zend_Paginator::factory ( $select );
	}
	
	public function getLikeCount($object) {
		if (is_string ( $object )) {
			$object = Engine_Api::_ ()->getItemByGuid ( $object );
		}
		
		if (! ($object instanceof Core_Model_Item_Abstract) || ! $object->getIdentity ()) {
			return null;
		}
		
		$table = Engine_Api::_ ()->getDbTable ( 'likes', 'core' );
		return $table->getLikeCount ( $object );
	}
	
	public function getLikesCount($object, array $object_ids) {
		if (empty ( $object_ids )) {
			return false;
		}
		
		$table = Engine_Api::_ ()->getDbTable ( 'likes', 'core' );
		$name = $table->info ( 'name' );
		$resource_ids = implode ( ",", $object_ids );
		
		$select = $table->select ()->setIntegrityCheck ( false )->from ( $name, array ('object_id' => $name . '.resource_id', 'count' => 'COUNT(*)' ) )->where ( $name . '.resource_type = ?', $object )->where ( $name . '.resource_id IN (' . $resource_ids . ')' )->group ( $name . '.resource_id' );
		
		$db = $table->getAdapter ();
		return $db->fetchPairs ( $select );
	}
	
	public function getToday() {
		$timestamp = time ();
		$today = getdate ( $timestamp );
		$month = $today ['mon'];
		$mday = $today ['mday'];
		$year = $today ['year'];
		return date ( 'Y-m-d H:i:s', mktime ( 0, 0, 0, $month, $mday, $year ) );
	}
	
	public function getFriends($params) {
		if (! empty ( $params ['user_id'] )) {
			$user_id = $params ['user_id'];
		} else {
			$user_id = Engine_Api::_ ()->user ()->getViewer ()->getIdentity ();
		}
		
		if (! empty ( $params ['list_type'] ) && $params ['list_type'] == 'mutual') {
			return $this->getMutualFriends ( $params );
		}
		
		$table = Engine_Api::_ ()->getItemTable ( 'user' );
		$name1 = $table->info ( 'name' );
		
		$membershipTable = Engine_Api::_ ()->getDbTable ( 'membership', 'user' );
		$name2 = $membershipTable->info ( 'name' );
		
		$select = $table->select ()->setIntegrityCheck ( false );
		
		if (! empty ( $params ['fetch'] )) {
			if ($params ['fetch'] == 'user_id') {
				$select->from ( $name1, array ($name1 . '.user_id' ) );
			}
		} else {
			$select->from ( $name1 );
		}
		
		$select->joinLeft ( $name2, $name2 . '.user_id = ' . $name1 . '.user_id', array () )->where ( $name2 . '.resource_id = ?', $user_id )->where ( $name2 . '.resource_approved = 1' )->where ( $name2 . '.user_approved = 1' );
		
		if (! empty ( $params ['fetch'] )) {
			if ($params ['fetch'] == 'user_id') {
				return $table->getAdapter ()->fetchCol ( $select );
			}
		} else {
			return Zend_Paginator::factory ( $select );
		}
	}
	
	public function getMutualFriends($params) {
		if (! empty ( $params ['user_id'] )) {
			$user_id = $params ['user_id'];
		}
		
		if (! empty ( $params ['list_type'] ) && $params ['list_type'] == 'all') {
			return $this->getFriends ( $params );
		}
		
		$viewer = Engine_Api::_ ()->user ()->getViewer ();
		
		$friendsTable = Engine_Api::_ ()->getDbtable ( 'membership', 'user' );
		$friendsName = $friendsTable->info ( 'name' );
		
		$select = new Zend_Db_Select ( $friendsTable->getAdapter () );
		$select->from ( $friendsName, 'user_id' )->join ( $friendsName, "`{$friendsName}`.`user_id`=`{$friendsName}_2`.user_id", null )->where ( "`{$friendsName}`.resource_id = ?", $viewer->getIdentity () )->where ( "`{$friendsName}_2`.resource_id = ?", $user_id )->where ( "`{$friendsName}`.active = ?", 1 )->where ( "`{$friendsName}_2`.active = ?", 1 );
		
		$uids = array ();
		foreach ( $select->query ()->fetchAll () as $data ) {
			$uids [] = $data ['user_id'];
		}
		
		if (count ( $uids ) > 0) {
			$UTable = Engine_Api::_ ()->getItemTable ( 'user' );
			$select = $UTable->select ()->where ( 'user_id IN(?)', $uids );
			$paginator = Zend_Paginator::factory ( $select );
		} else {
			$paginator = Zend_Paginator::factory ( array () );
		}
		
		return $paginator;
	}
	
	public function getLikedItems($user = null, $categorized = false, $period = 'all') {
		if ($user === null) {
			$user = Engine_Api::_ ()->user ()->getViewer ();
		}
		
		if (is_numeric ( $user )) {
			$user = Engine_Api::_ ()->getItem ( 'user', $user );
		}
		
		if (! ($user instanceof User_Model_User) || ! $user->getIdentity ()) {
			return null;
		}
		$itemTypes = array_keys ( $this->getSupportedModulesLabels () );
		$table = Engine_Api::_ ()->getDbTable ( 'likes', 'core' );
		$select = $table->select ()->where ( 'poster_type = ?', $user->getType () )->where ( 'poster_id = ?', $user->getIdentity () )->where ( 'resource_type IN ("' . implode ( '","', $itemTypes ) . '")' );
		
		if ($period == 'month') {
			$select->where ( 'creation_date > ?', new Zend_Db_Expr ( 'DATE_SUB(NOW(), INTERVAL 1 MONTH)' ) );
		} elseif ($period == 'week') {
			$select->where ( 'creation_date > ?', new Zend_Db_Expr ( 'DATE_SUB(NOW(), INTERVAL 1 WEEK)' ) );
		}
		
		$rawData = $table->fetchAll ( $select );
		$items = array ();
		
		foreach ( $rawData as $data ) {
			if ($categorized) {
				$items [$data->resource_type] [] = Engine_Api::_ ()->getItem ( $data->resource_type, $data->resource_id );
			} else {
				$items [] = Engine_Api::_ ()->getItem ( $data->resource_type, $data->resource_id );
			}
		}
		
		return $items;
	}
	
	public function getLikedCount($user = null, $period = 'all') {
		if ($user === null) {
			$user = Engine_Api::_ ()->user ()->getViewer ();
		}
		
		if (is_numeric ( $user )) {
			$user = Engine_Api::_ ()->getItem ( 'user', $user );
		}
		
		if (! ($user instanceof User_Model_User) || ! $user->getIdentity ()) {
			return null;
		}
		
		$itemTypes = array_keys ( $this->getSupportedModulesLabels () );
		$table = Engine_Api::_ ()->getDbTable ( 'likes', 'core' );
		$name = $table->info ( 'name' );
		$select = $table->select ()->setIntegrityCheck ( false )->from ( $name, array ('count' => 'COUNT(*)' ) )->where ( 'poster_type = ?', 'user' )->where ( 'poster_id = ?', $user->getIdentity () )->where ( 'resource_type IN ("' . implode ( '","', $itemTypes ) . '")' );
		
		if ($period == 'month') {
			$select->where ( 'creation_date > ?', new Zend_Db_Expr ( 'DATE_SUB(NOW(), INTERVAL 1 MONTH)' ) );
		} elseif ($period == 'week') {
			$select->where ( 'creation_date > ?', new Zend_Db_Expr ( 'DATE_SUB(NOW(), INTERVAL 1 WEEK)' ) );
		}
		$db = $table->getAdapter ();
		
		return $db->fetchOne ( $select );
	}
	
	public function getMostLiked($type, $limit = null, $period = 'all') {
		if (! $type) {
			return false;
		}
		
		$table = Engine_Api::_ ()->getDbTable ( 'likes', 'core' );
		$name = $table->info ( 'name' );
		$select = $table->select ()->setIntegrityCheck ( false )->from ( array ('like' => $name ), array ('resource_id', 'like_count' => 'COUNT(*)' ) )->where ( 'resource_type = ?', $type )->order ( 'like_count DESC' )->group ( 'resource_id' );
		
		if ($limit) {
			$select->limit ( $limit );
		}
		
		if ($period == 'month') {
			$select->where ( 'creation_date > ?', new Zend_Db_Expr ( 'DATE_SUB(NOW(), INTERVAL 1 MONTH)' ) );
		} elseif ($period == 'week') {
			$select->where ( 'creation_date > ?', new Zend_Db_Expr ( 'DATE_SUB(NOW(), INTERVAL 1 WEEK)' ) );
		}
		
		$rawData = $table->getAdapter ()->fetchPairs ( $select );
		$ids = array_keys ( $rawData );
		
		if (! empty ( $ids )) {
			return array ('paginator' => Zend_Paginator::factory ( Engine_Api::_ ()->getItemMulti ( $type, $ids ) ), 'counts' => $rawData );
		} else {
			if ($period == 'all') {
				return false;
			} else {
				return array ('paginator' => Zend_Paginator::factory ( Engine_Api::_ ()->getItemMulti ( $type, $ids ) ), 'counts' => $rawData );
			}
		}
	}
	
	public function getAllLikesUsers(Core_Model_Item_Abstract $resource, $period = 'all') {
		$likes = new Core_Model_DbTable_Likes ();
		$table = $likes->getLikeTable ();
		$select = new Zend_Db_Select ( $table->getAdapter () );
		$select->from ( $table->info ( 'name' ), array ('poster_type', 'poster_id' ) )->where ( 'resource_type = ?', $resource->getType () )->where ( 'resource_id = ?', $resource->getIdentity () );
		
		if ($period == 'month') {
			$select->where ( 'creation_date > ?', new Zend_Db_Expr ( 'DATE_SUB(NOW(), INTERVAL 1 MONTH)' ) );
		} elseif ($period == 'week') {
			$select->where ( 'creation_date > ?', new Zend_Db_Expr ( 'DATE_SUB(NOW(), INTERVAL 1 WEEK)' ) );
		}
		
		$users = array ();
		foreach ( $select->query ()->fetchAll () as $data ) {
			if ($data ['poster_type'] == 'user') {
				$users [] = $data ['poster_id'];
			}
		}
		$users = array_values ( array_unique ( $users ) );
		
		return Engine_Api::_ ()->getItemMulti ( 'user', $users );
	}
}